using System;
using System.Reflection;
using System.Collections.Generic;
using System.Windows.Forms;

namespace SBPweb.Themes.Windows.Schemes
{
	/// <summary>
	/// Class of StyleSheetBindingBase
	/// </summary>
    public abstract class StyleSheetBindingBase// : Dictionary<string, PropertyInfo>
    {
		/// <summary>
		/// Type
		/// </summary>
        protected Type pT = typeof(Control);
		/// <summary>
		/// Dictionary of propertyinfos
		/// </summary>
        protected Dictionary<string, PropertyInfo> pDictPIs = new Dictionary<string, PropertyInfo>();
		/// <summary>
		/// Dictionary of event handlers
		/// </summary>
        protected Dictionary<string, EventHandler<StyleSheetBindingEventArgs>> pDictEHs = new Dictionary<string, EventHandler<StyleSheetBindingEventArgs>>();

		/// <summary>
		/// Constructor of StyleSheetBindingBase
		/// </summary>
        static StyleSheetBindingBase()
        {
        }

        internal void SetValue(KeyValuePair<string, string> kvp, Control control)
        {
            if (!pDictPIs.ContainsKey(kvp.Key))
            {
                return;
            }
            PropertyInfo pI = pDictPIs[kvp.Key];
            if (!pI.CanWrite)
            {
                return;
            }

            KeyValuePair<object, object[]> prms = ConvertSetValueParams(kvp, control);
            pI.SetValue(control, prms.Key, prms.Value);
        }

		/// <summary>
		/// Register property bind
		/// </summary>
		/// <param name="attributeName">attribute name</param>
		/// <param name="propertyName">property name</param>
		/// <param name="onGetValues">event of get values</param>
		protected void RegisterPropertyBind(string attributeName, string propertyName, EventHandler<StyleSheetBindingEventArgs> onGetValues)
        {
            RegisterPropertyBind<Control>(attributeName, propertyName, onGetValues);
        }

		/// <summary>
		/// Register property bind
		/// </summary>
		/// <typeparam name="T">type</typeparam>
		/// <param name="attributeName">attribute name</param>
		/// <param name="propertyName">property name</param>
		/// <param name="onGetValues">event of get values</param>
        protected void RegisterPropertyBind<T>(string attributeName, string propertyName, EventHandler<StyleSheetBindingEventArgs> onGetValues) where T : Control
        {
            if (!pDictPIs.ContainsKey(attributeName))
            {
                pDictPIs.Add(attributeName, GetPropertyInfo<T>(propertyName));
            }
            if (!pDictEHs.ContainsKey(attributeName))
            {
                pDictEHs.Add(attributeName, onGetValues);
            }
            else
            {
                pDictEHs[attributeName] += onGetValues;
            }
        }

		/// <summary>
		/// Convert set value params
		/// </summary>
		/// <param name="kvp">key value pair</param>
		/// <param name="control">control</param>
		/// <returns>key value pair</returns>
        private KeyValuePair<object, object[]> ConvertSetValueParams(KeyValuePair<string, string> kvp, Control control)
        {
            StyleSheetBindingEventArgs ssbea = new StyleSheetBindingEventArgs(kvp.Key, kvp.Value);
            if (pDictEHs.ContainsKey(kvp.Key))
            {
                pDictEHs[kvp.Key].Invoke(control, ssbea);
            }
            return new KeyValuePair<object, object[]>(ssbea.BindValue, ssbea.Idexes);
        }

        private PropertyInfo GetPropertyInfo<T>(string name) where T : Control
        {
            return typeof(T).GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Default);
        }
    }

}
